package top.lcm889.juc.线程安全问题.model;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Coder-lcm
 * @date 2021/4/10
 */
public class Account3 {
    private String No;
    private double balance;
    private boolean flag = false; //存钱的标志
    // 可重入锁
    private final Lock lock = new ReentrantLock();
    // 锁的条件变量
    private final Condition condition = lock.newCondition();

    public Account3(String no, double balance) {
        No = no;
        this.balance = balance;
    }

    public String getNo() {
        return No;
    }

    public void setNo(String no) {
        No = no;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Lock getLock() {
        return lock;
    }

    public Condition getCondition() {
        return condition;
    }

    /**
     * 存钱
     * @param money
     */
    public void plusMoney(double money) {
        lock.lock();
        try {
            if (flag) { //如果上一个线程已经存钱了，则先阻塞线程
                //线程阻塞，效果类似于Object.wait()
                System.out.println(Thread.currentThread().getName() + " 存钱阻塞");
                condition.await();
            }else {
                //进行存钱操作
                System.out.println(Thread.currentThread().getName() + ": 存钱 " + money);
                balance += money;
                System.out.println(Thread.currentThread().getName() + " 余额：" + balance);
                // 通知所有等待的线程 。效果类似于Object.notifyAll()
                condition.signalAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 取钱
     * @param money
     */
    public void reduceMoney(double money) {
        lock.lock();
        try {
            if (!flag) { //如果上一个线程已经存钱了，则先阻塞线程
                //线程阻塞，效果类似于Object.wait()
                System.out.println(Thread.currentThread().getName() + " 取钱阻塞");
                condition.await();
            }else {
                //进行取钱操作
                System.out.println(Thread.currentThread().getName() + ": 取钱 " + money);
                balance -= money;
                System.out.println(Thread.currentThread().getName() + " 余额：" + balance);
                // 通知所有等待的线程 。效果类似于Object.notifyAll()
                condition.signalAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
